Conversation
… pointers When a .git file contains a relative gitdir: path (as used by submodules and linked worktrees), get_git_branch() was calling g_free() on its own const char* parameter, then the caller would free the same pointer again. This double-free causes heap corruption that manifests as a crash when enumerating a parent directory containing such a submodule. Fix by introducing a separate resolved_gitdir variable to hold the heap-allocated resolved path, leaving the parameter untouched. Use realpath() to canonicalise ../ components in relative paths, and guard against a NULL return when the target path does not exist on disk. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
lukefromdc
reviewed
Jun 4, 2026
lukefromdc
left a comment
Member
There was a problem hiding this comment.
Looking closely at this due to its AI origin. I don't see any obvious AI screwups here, but I don't know this part of the code well enough to follow the flow of it from just what we see here
Member
|
The commit in this PR is included in #1893, which I reviewed earlier today. I think we should leave this here open for now until we decide whether we use one or the other (the fix is valid in either case, with some small changes) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When Caja enumerates a directory whose subdirectories contain a
.gitfile(rather than a
.gitdirectory — as used by git submodules and linkedworktrees),
get_git_branch()crashes intermittently via heap corruption.The root cause is a double-free:
get_git_branch(), when.gitis a regular file the code callsg_free(git_path)on its ownconst char *parameter (to free thecaller's allocation before reassigning the local variable).
g_free(git_path)again on the same pointer afterget_git_branch()returns.The resulting heap corruption is non-deterministic — it manifests as a crash
elsewhere in the process, not at the site of the double-free, which is why a
desktop code review found no obvious NULL-dereference path in the feature code.
A secondary issue:
g_build_filename()does not canonicalise../componentsin relative
gitdir:paths. If the resolved path does not exist on disk(e.g. an uninitialised submodule),
realpath()returns NULL; without a guardthis would be passed into subsequent GLib calls.
Fix
resolved_gitdirlocal variable to hold the heap-allocatedresolved path. The
git_pathparameter (which belongs to the caller) isnever freed inside the function.
realpath()to canonicalise relativegitdir:paths containing../components. The result is copied into GLib-managed memory with
g_strdup()and the
malloc()-allocatedrealpath()buffer is freed withfree().realpath()— when the target path isabsent on disk,
effective_gitdiris set to NULL and the subsequentg_file_test()call is skipped cleanly.#include <stdlib.h>forrealpath()andfree().Crash reproduction
Navigate to a parent directory in Caja icon view that contains a subdirectory
with a
.gitfile whosegitdir:line holds a relative path(e.g.
gitdir: ../../../../../.git/modules/...). With the Display Git Branchpreference enabled, Caja crashes on directory enumeration. After this fix,
enumeration completes without crashing.